package cn.tx.redislock.test;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author jizenan
 * @date 2025/6/9
 * Description:
 */
public class ReEntryLockDemo {

    final Object obj = new Object();

    public static void main(String[] args) {
        ReEntryLockDemo demo = new ReEntryLockDemo();
        //demo.entry01();
        //demo.entry02();
        demo.entry03();
    }

    public void entry01(){
        new Thread(()->{
            synchronized (obj){
                System.out.println(Thread.currentThread().getName()+"\t"+"外层调用");
                synchronized (obj){
                    System.out.println(Thread.currentThread().getName()+"\t"+"中层调用");
                    synchronized (obj){
                        System.out.println(Thread.currentThread().getName()+"\t"+"内层调用");
                    }
                }
            }
        },"t1").start();
    }

    public void entry02(){
        m1();
    }

    private synchronized void m1() {
        System.out.println(Thread.currentThread().getName()+"\t"+"外层调用synchronized");
        m2();
    }

    private synchronized void m2() {
        System.out.println(Thread.currentThread().getName()+"\t"+"中层调用synchronized");
        m3();
    }

    private synchronized void m3() {
        System.out.println(Thread.currentThread().getName()+"\t"+"内层调用synchronized");
    }

    Lock lock = new ReentrantLock();

    //在一个synchronized修饰的方法或代码块的内部调用本类的其他synchronized修饰的方法或代码块时，是永远可以得到的
    public void entry03(){
        new Thread(()->{
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName()+"\t"+"外层调用lock");
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName()+"\t"+"内层调用lock");
                } finally {
                    lock.unlock();
                }
            } finally {
                lock.unlock();
            }
        },"t1").start();

        try {Thread.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName()+"\t"+"外层调用lock");
            } finally {
                lock.unlock();
            }

        },"t2").start();
    }
}
